package com.ruoyi.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.JobTypeInitEnum;
import com.ruoyi.common.enums.YnStatusEnum;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.AppCreateJobBill;
import com.ruoyi.system.domain.AppCreateJobBillV2;
import com.ruoyi.system.domain.JobPlanBillDeclare;
import com.ruoyi.system.domain.MesSendOrderConfig;
import com.ruoyi.system.domain.bill.AppCreateBill;
import com.ruoyi.system.domain.vo.DeleteVo;
import com.ruoyi.system.domain.vo.JobTypeCountVO;
import com.ruoyi.system.entity.AppJobSignedConfig;
import com.ruoyi.system.entity.SysActing;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.AppCreateJobBillService;
import com.ruoyi.system.service.JobPlanBillDeclareService;
import com.ruoyi.system.service.SysActingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * App创建作业票(AppCreateJobBill)表服务实现类
 *
 * @author makejava
 * @since 2022-12-08 15:21:48
 */
@Slf4j
@Service("appCreateJobBillService")
public class AppCreateJobBillServiceImpl implements AppCreateJobBillService {
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private SysActingService sysActingService;
    @Resource
    private EnterpriseWXServiceImpl enterpriseWXService;
    @Autowired
    private JobPlanBillDeclareService jobPlanBillDeclareService;

    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private AppCreateJobBillMapper appCreateJobBillDao;
    @Resource
    private AppCreateJobBillVMapper appCreateJobBillVMapper;
    @Resource
    private AppJobSignedConfigMapper appJobSignedConfigMapper;
    @Resource
    private MesSendOrderConfigMapper mesSendOrderConfigMapper;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public AppCreateJobBill queryById(Integer id) {
        return this.appCreateJobBillDao.queryById(id);
    }

    /**
     * 分页查询
     *
     * @param appCreateJobBill 筛选条件
     * @param pageRequest      分页对象
     * @return 查询结果
     */
    @Override
    public Page<AppCreateJobBill> queryByPage(AppCreateJobBill appCreateJobBill, PageRequest pageRequest) {
        long total = this.appCreateJobBillDao.count(appCreateJobBill);
        return new PageImpl<>(this.appCreateJobBillDao.queryAllByLimit(appCreateJobBill, pageRequest), pageRequest, total);
    }

    @Override
    public List<AppCreateJobBill> queryAll(AppCreateJobBill appCreateJobBill) {
        appCreateJobBill.setYn(YnStatusEnum.Y.getCode());
        List<AppCreateJobBill> list = appCreateJobBillDao.queryAll(appCreateJobBill);

        if (StringUtils.isNotEmpty(list)) {
            list.forEach(val -> {
                String content = val.getContent();
                JSONObject contentJson = JSONObject.parseObject(content);
                JSONArray jsonArray = contentJson.getJSONArray("qitiData");
                // 新增：对qitiData数组按fxsj字段降序排序（最新时间在前）
                if (jsonArray != null && !jsonArray.isEmpty()) {
                    // 转换为List以便排序
                    List<JSONObject> qitiDataList = jsonArray.toJavaList(JSONObject.class);
                    // 按fxsj字段排序（降序）
                    qitiDataList.sort((o1, o2) -> {
                        String fxsj1 = o1.getString("fxsj");
                        String fxsj2 = o2.getString("fxsj");
                        try {
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                            Date date1 = sdf.parse(fxsj1);
                            Date date2 = sdf.parse(fxsj2);
                            // 降序排序（最新的在前），如果需要升序则使用date1.compareTo(date2)
                            return date2.compareTo(date1);
                        } catch (ParseException e) {
                            log.error("解析fxsj日期失败: {}", e.getMessage());
                            // 解析失败时保持原顺序
                            return 0;
                        }
                    });
                    // 将排序后的列表转换回JSONArray并更新
                    contentJson.put("qitiData", JSONArray.parseArray(JSON.toJSONString(qitiDataList)));
                    val.setContent(contentJson.toJSONString());
                }
            });
        }

        return list;
    }

    /**
     * 新增数据
     *
     * @param appCreateJobBill 实例对象
     * @return 实例对象
     */
    @Override
    public AppCreateJobBill insert(AppCreateJobBill appCreateJobBill) {
        AppCreateBill appCreateBill = new AppCreateBill();
        appCreateBill.setBillType(Integer.valueOf(appCreateJobBill.getJobType()));
        String number = createNumber(appCreateBill);
        appCreateJobBill.setSpecialNumber(number);
        appCreateJobBill.setCreatedDate(new Date());
        appCreateJobBill.setYn(YnStatusEnum.Y.getCode());

        appCreateJobBill.setIsUpload(0);
        int insert = this.appCreateJobBillDao.insert(appCreateJobBill);
        if (insert > 0) {
            if (StringUtils.isNotEmpty(appCreateJobBill.getChangeBillNumberId())
                    && StringUtils.isNotEmpty(appCreateJobBill.getChangeBillNumber())) {

                List<String> ids = new ArrayList<>();
                if (appCreateJobBill.getChangeBillNumberId().contains(",")) {
                    String[] split = appCreateJobBill.getChangeBillNumberId().split(",");
                    ids.addAll(Arrays.asList(split));
                } else {
                    ids.add(appCreateJobBill.getChangeBillNumberId());
                }

                List<AppCreateJobBill> appCreateJobBills = appCreateJobBillDao.queryInId(ids);
                if (!CollectionUtils.isEmpty(appCreateJobBills)) {
                    appCreateJobBills.forEach(val -> {
                        AppCreateJobBill updAppCreateJobBill = new AppCreateJobBill();
                        updAppCreateJobBill.setId(val.getId());
                        if (StringUtils.isNotEmpty(val.getChangeBillNumberId())) {
                            updAppCreateJobBill.setChangeBillNumberId(val.getChangeBillNumberId() + "," + appCreateJobBill.getId());
                        } else {
                            updAppCreateJobBill.setChangeBillNumberId(appCreateJobBill.getId().toString());
                        }
                        if (StringUtils.isNotEmpty(val.getChangeBillNumber())) {
                            updAppCreateJobBill.setChangeBillNumber(val.getChangeBillNumber() + "," + number);
                        } else {
                            updAppCreateJobBill.setChangeBillNumber(number);
                        }
                        appCreateJobBillDao.update(updAppCreateJobBill);
                    });
                }
            }
        }

        try {
            String desc = JobTypeInitEnum.valueOfCode(Integer.valueOf(appCreateJobBill.getJobType())).getDesc();

            AppJobSignedConfig appJobSignedConfig = new AppJobSignedConfig();
            appJobSignedConfig.setYn(YnStatusEnum.Y.getCode());
            appJobSignedConfig.setJobType(appCreateJobBill.getJobType());
            if (appCreateJobBill.getJobType().equals(JobTypeInitEnum.HOT_WORK_SECURITY_JOB_BILL.getCode().toString())) {
                JSONObject jsonObject = JSON.parseObject(appCreateJobBill.getContent());
                appJobSignedConfig.setJobGrade(jsonObject.get("dhzyjb").toString());
            }

            List<AppJobSignedConfig> appJobSignedConfigList = appJobSignedConfigMapper.queryAll(appJobSignedConfig);

            appJobSignedConfigList = appJobSignedConfigList.stream()
                    .collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
                            new TreeSet<>(Comparator.comparing(AppJobSignedConfig::getSignedBy))), ArrayList::new));

            JobPlanBillDeclare jobPlanBillDeclare = new JobPlanBillDeclare();
            jobPlanBillDeclare.setBillNumber(appCreateJobBill.getPtw());
            List<JobPlanBillDeclare> jobPlanBillDeclares = jobPlanBillDeclareService.queryAll(jobPlanBillDeclare);
            JobPlanBillDeclare planBillDeclare = jobPlanBillDeclares.stream().findFirst().orElse(new JobPlanBillDeclare());

            sendJobSignToNeed(appJobSignedConfigList, planBillDeclare.getBillNumber(), desc,
                    appCreateJobBill.getSpecialNumber(), appCreateJobBill.getJobStartDate());
        } catch (Exception e) {
            log.info("开票通知异常:{}", e.toString());
        }

        return appCreateJobBill;
    }

    private void sendJobSignToNeed(List<AppJobSignedConfig> appJobSignedConfigList, String pwt, String billName, String builCode, String time) {
        List<SysActing> sysActings = new ArrayList<>();
        appJobSignedConfigList.forEach(var -> {
            String planName = "作业计划" + pwt + "开具" + billName + builCode + ", 请于" + time + "前审批完成！";
            SysActing sysActing = new SysActing();
            sysActing.setTitleName("新开特殊作业票");
            sysActing.setTitleType("作业票");
            sysActing.setTitleInfo(planName);
            sysActing.setOriginatorId(1);
            sysActing.setOriginatorName("admin");
            sysActing.setExecutorId(var.getSignedBy());
            sysActing.setExecutorName(var.getSignedName());
            sysActing.setState(YnStatusEnum.N.getCode());
            sysActing.setCreateTime(LocalDateTime.now());
            sysActings.add(sysActing);
        });
        sysActingService.insertBatch(sysActings);

        List<Integer> list = appJobSignedConfigList.stream().map(AppJobSignedConfig::getSignedBy).collect(Collectors.toList());
        List<SysUser> vidsInfo = sysUserMapper.getVidsInfo(list);
        if (CollectionUtils.isEmpty(vidsInfo)) {
            return;
        }

        EnterpriseWXServiceImpl.SendMessageRequest sendMessageRequest = new EnterpriseWXServiceImpl.SendMessageRequest();
        sendMessageRequest.setTouser(vidsInfo.stream().map(SysUser::getWxUserId).collect(Collectors.joining("|")));
        sendMessageRequest.setMsgtype("text");
        sendMessageRequest.setAgentid(1000319);
        EnterpriseWXServiceImpl.MessageContent messageContent = new EnterpriseWXServiceImpl.MessageContent();
        messageContent.setContent("作业计划" + pwt + "开具" + billName + builCode + ", 请于" + time + "前审批完成！");
        sendMessageRequest.setText(messageContent);
        enterpriseWXService.pushMessage(sendMessageRequest);
    }

    @Override
    public AppCreateJobBillV2 insertV2(AppCreateJobBillV2 appCreateJobBillV2) {
        AppCreateBill appCreateBill = new AppCreateBill();
        appCreateBill.setBillType(Integer.valueOf(appCreateJobBillV2.getJobType()));
        String number = createNumber(appCreateBill);
        appCreateJobBillV2.setSpecialNumber(number);
        this.appCreateJobBillVMapper.insert(appCreateJobBillV2);
        return appCreateJobBillV2;
    }

    /**
     * 修改数据
     *
     * @param appCreateJobBill 实例对象
     * @return 实例对象
     */
    @Override
    public AppCreateJobBill update(AppCreateJobBill appCreateJobBill) {
        String content = mergeJson(appCreateJobBill);
        appCreateJobBill.setContent(content);
        appCreateJobBill.setIsUpload(0);
        this.appCreateJobBillDao.update(appCreateJobBill);
        this.queryById(appCreateJobBill.getId());

        try {
            boolean flag = false;
            boolean checkFlag = false;

            final Map<String, String> initMap = new HashMap<>();
            initMap.put("1", "yjqm5");
            initMap.put("2", "yjqm7");
            initMap.put("3", "yjqm5");
            initMap.put("4", "yjqm5");
            initMap.put("5", "yjqm5");
            initMap.put("6", "yjqm5");
            initMap.put("7", "yjqm4");
            initMap.put("8", "yjqm4");
            initMap.put("9", "yjqm4");
            initMap.put("10", "yjqm5");
            AppCreateJobBill createJobBill = appCreateJobBillDao.queryById(appCreateJobBill.getId());
            if (null == createJobBill) {
                return appCreateJobBill;
            }

            String value = initMap.get(createJobBill.getJobType());
            JSONObject jsonObject = JSON.parseObject(createJobBill.getContent());
            if (jsonObject.containsKey(value) && null != jsonObject.get(value)) {
                flag = true;
            }

            if (flag) {
                String desc = JobTypeInitEnum.valueOfCode(Integer.valueOf(appCreateJobBill.getJobType())).getDesc();

                JobPlanBillDeclare jobPlanBillDeclare = new JobPlanBillDeclare();
                jobPlanBillDeclare.setBillNumber(createJobBill.getPtw());
                List<JobPlanBillDeclare> jobPlanBillDeclares = jobPlanBillDeclareService.queryAll(jobPlanBillDeclare);
                JobPlanBillDeclare planBillDeclare = jobPlanBillDeclares.stream().findFirst().orElse(new JobPlanBillDeclare());

                List<AppJobSignedConfig> appJobSignedConfigList = new ArrayList<>();
                AppJobSignedConfig appJobSignedConfig = new AppJobSignedConfig();
                appJobSignedConfig.setSignedBy(Integer.valueOf(planBillDeclare.getApplyPeopleId()));
                appJobSignedConfig.setSignedName(planBillDeclare.getApplyPeople());
                appJobSignedConfigList.add(appJobSignedConfig);
                sendJobSignToNeedUpdName(appJobSignedConfigList, planBillDeclare.getBillNumber(), desc, createJobBill.getSpecialNumber(), checkFlag);
            }

            try {
                seekNextNode(createJobBill);
            } catch (Exception e) {
                log.error("签批通知异常:{}", e.toString());
            }

        } catch (Exception e) {
            log.error("关闭作业票异常:{}", e.toString());
        }

        return appCreateJobBill;
    }

    private void sendJobSignToNeedUpdName(List<AppJobSignedConfig> appJobSignedConfigList, String pwt, String billName, String builCode, boolean flag) {
        List<SysActing> sysActings = new ArrayList<>();
        appJobSignedConfigList.forEach(var -> {
            String planName = "";
            if (flag) {
                planName = "作业计划" + pwt + billName + builCode + "已关闭，已超出作业结束时间！";
            } else {
                planName = "作业计划" + pwt + billName + builCode + "在预定的作业时间内关闭";
            }
            SysActing sysActing = new SysActing();
            sysActing.setTitleName("签批特殊作业票");
            sysActing.setTitleType("");
            sysActing.setTitleInfo(planName);
            sysActing.setOriginatorId(1);
            sysActing.setOriginatorName("admin");
            sysActing.setExecutorId(var.getSignedBy());
            sysActing.setExecutorName(var.getSignedName());
            sysActing.setState(YnStatusEnum.N.getCode());
            sysActings.add(sysActing);
        });
        sysActingService.insertBatch(sysActings);

        List<Integer> list = appJobSignedConfigList.stream().map(AppJobSignedConfig::getSignedBy).collect(Collectors.toList());
        List<SysUser> vidsInfo = sysUserMapper.getVidsInfo(list);
        if (CollectionUtils.isEmpty(vidsInfo)) {
            return;
        }

        EnterpriseWXServiceImpl.SendMessageRequest sendMessageRequest = new EnterpriseWXServiceImpl.SendMessageRequest();
        sendMessageRequest.setTouser(vidsInfo.stream().map(SysUser::getWxUserId).collect(Collectors.joining("|")));
        sendMessageRequest.setMsgtype("text");
        sendMessageRequest.setAgentid(1000319);
        EnterpriseWXServiceImpl.MessageContent messageContent = new EnterpriseWXServiceImpl.MessageContent();
        String planName = "";
        if (flag) {
            planName = "作业计划" + pwt + billName + builCode + "已关闭，已超出作业结束时间！";
        } else {
            planName = "作业计划" + pwt + billName + builCode + "在预定的作业时间内关闭";
        }
        messageContent.setContent(planName);
        sendMessageRequest.setText(messageContent);
        enterpriseWXService.pushMessage(sendMessageRequest);
    }

    /**
     * 通过主键删除数据
     *
     * @param deleteVo 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(DeleteVo deleteVo) {
        Integer id = deleteVo.getId();
        AppCreateJobBill appCreateJobBill = appCreateJobBillDao.queryById(id);
        String specialNumber = appCreateJobBill.getSpecialNumber();

        List<AppCreateJobBill> appCreateJobBills = appCreateJobBillDao.concatChangeBillNumber(specialNumber);
        if (!CollectionUtils.isEmpty(appCreateJobBills)) {
            for (AppCreateJobBill var : appCreateJobBills) {
                String billNumberIds = var.getChangeBillNumberId();
                if (StringUtils.isEmpty(billNumberIds))  { continue; }
                billNumberIds = Arrays.stream(billNumberIds.split(","))
                        .filter(numberId -> !numberId.trim().equals(id+""))
                        .collect(Collectors.joining(","));
                var.setChangeBillNumberId(billNumberIds);

                String billNumbers = var.getChangeBillNumber();
                if (StringUtils.isEmpty(billNumbers))  { continue; }
                billNumbers = Arrays.stream(billNumbers.split(","))
                        .filter(number -> !number.trim().equals(specialNumber))
                        .collect(Collectors.joining(","));
                var.setChangeBillNumber(billNumbers);

//                boolean contains = var.getChangeBillNumberId().contains(id + ",");
//                if (contains) {
//                    var.setChangeBillNumberId(var.getChangeBillNumberId().replace(id + ",", ""));
//                } else {
//                    boolean containsFlag = var.getChangeBillNumberId().contains("," + id.toString());
//                    if (containsFlag) {
//                        var.setChangeBillNumberId(var.getChangeBillNumberId().replace("," + id.toString(), ""));
//                    } else {
//                        var.setChangeBillNumberId(var.getChangeBillNumberId().replace(id.toString(), ""));
//                    }
//                }
//                boolean containsNumber = var.getChangeBillNumber().contains(appCreateJobBill.getSpecialNumber() + ",");
//                if (containsNumber) {
//                    var.setChangeBillNumber(var.getChangeBillNumber().replace(appCreateJobBill.getSpecialNumber() + ",", ""));
//                } else {
//                    boolean containsFlag = var.getChangeBillNumber().contains("," + appCreateJobBill.getSpecialNumber());
//                    if (containsFlag) {
//                        var.setChangeBillNumber(var.getChangeBillNumber().replace("," + appCreateJobBill.getSpecialNumber(), ""));
//                    } else {
//                        var.setChangeBillNumber(var.getChangeBillNumber().replace(appCreateJobBill.getSpecialNumber(), ""));
//                    }
//                }

                appCreateJobBillDao.updateOne(var);
            }
        }

        AppCreateJobBill appCreateJobBillUpd = new AppCreateJobBill();
        appCreateJobBillUpd.setId(id);
        appCreateJobBillUpd.setYn(YnStatusEnum.N.getCode());
        appCreateJobBillUpd.setYnReason(deleteVo.getYnReason());
        appCreateJobBillDao.updateOne(appCreateJobBillUpd);

        return true;
    }

    @Override
    public String createNumber(AppCreateBill appCreateBill) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        String format = simpleDateFormat.format(new Date());

        String number = "";
        String key = "APP_BILL_";

        String billType = buildBillType(appCreateBill.getBillType());
        String value = billType + "-" + format + "-";
        key += billType;

        if (redisCache.hasKey(key)) {
            Object cacheObject = redisCache.getCacheObject(key);
            int no = Integer.parseInt((String) cacheObject);
            int newEquipment = ++no;

            redisCache.setCacheObject(key, String.valueOf(newEquipment));
            return value + newEquipment;
        } else {
            redisCache.setCacheObject(key, "1");
            number = value + "1";
        }

        return number;
    }

    @Scheduled(cron = "59 59 23 * * ?")
    public void deleteR2mKey() {
        List<String> r2mKeys = new ArrayList<>();

        r2mKeys.add("APP_BILL_DZ");
        r2mKeys.add("APP_BILL_DH");
        r2mKeys.add("APP_BILL_GC");
        r2mKeys.add("APP_BILL_DT");
        r2mKeys.add("APP_BILL_YD");
        r2mKeys.add("APP_BILL_SX");
        r2mKeys.add("APP_BILL_DL");
        r2mKeys.add("APP_BILL_MB");
        r2mKeys.add("APP_BILL_KK");
        r2mKeys.add("APP_BILL_KJ");

        for (String var : r2mKeys) {
            redisCache.deleteObject(var);
        }

    }

    @Override
    public String mergeJson(AppCreateJobBill appCreateBill) {
        AppCreateJobBill appCreateJobBill = new AppCreateJobBill();
        appCreateJobBill.setSpecialNumber(appCreateBill.getSpecialNumber());
        List<AppCreateJobBill> appCreateJobBills = appCreateJobBillDao.queryAll(appCreateJobBill);
        if (CollectionUtils.isEmpty(appCreateJobBills)) {
            return appCreateBill.getContent();
        }

        AppCreateJobBill appCreateJobResp = appCreateJobBills.stream().findFirst().orElse(null);
        if (StringUtils.isEmpty(appCreateJobResp.getContent())) {
            return appCreateBill.getContent();
        }

        return jsonMerge(JSONObject.parseObject(appCreateBill.getContent()), JSONObject.parseObject(appCreateJobResp.getContent())).toJSONString();
    }

    @Override
    public AppCreateJobBill copy(AppCreateJobBill appCreateJobBill) {
        AppCreateJobBill appCreateJobBillResp = appCreateJobBillDao.queryById(appCreateJobBill.getId());
        appCreateJobBillResp.setContent(appCreateJobBill.getContent());
        appCreateJobBillResp.setChangeBillNumberId(null);
        appCreateJobBillResp.setChangeBillNumber(null);
        return this.insert(appCreateJobBillResp);
    }

    /**
     * 合并JSON对象，用source覆盖target，返回覆盖后的JSON对象。
     *
     * @param source JSONObject
     * @param target JSONObject
     * @return JSONObject
     */
    @SuppressWarnings("all")
    public static JSONObject jsonMerge(JSONObject source, JSONObject target) {
        List<String> splitStringKey = Arrays.asList("dhr", "dhrzsbh", "dyjrdjxkydgl", "yhsbjgl");
        if (target == null) {
            return source;
        }

        for (String key : source.keySet()) {
            Object value = source.get(key);
            if (!target.containsKey(key)) {
                target.put(key, value);
            } else {
                if (key.equals("jobDate")) {
                    target.put(key, source.get(key));
                    continue;
                }
                if (value instanceof JSONObject) {
                    JSONObject valueJson = (JSONObject) value;
                    JSONObject targetValue = jsonMerge(valueJson, target.getJSONObject(key));
                    target.put(key, targetValue);
                } else if (value instanceof JSONArray) {
                    JSONArray valueArray = (JSONArray) value;
                    if (valueArray.size() > 0) {
                        if (valueArray.get(0) instanceof String) {
                            Set<String> set = new HashSet<String>();
                            JSONArray jsonArray = new JSONArray();
                            if (null == target.get(key)) {
                                jsonArray = new JSONArray();
                            } else {
                                Object o = target.get(key).toString();
                                jsonArray = JSON.parseArray(o.toString());
                                if (CollUtil.isEmpty(jsonArray)) {
                                    jsonArray = new JSONArray();
                                }
                            }
                            jsonArray.forEach(s -> set.add(s.toString()));
                            valueArray.forEach(s -> set.add(s.toString()));
                            target.put(key, set.toArray());
                        } else {
                            for (int i = 0; i < valueArray.size(); i++) {
                                if (valueArray.get(i) instanceof JSONObject) {
                                    JSONObject obj = (JSONObject) valueArray.get(i);
                                    JSONArray jsonArray = target.getJSONArray(key);
                                    if (!(target.getJSONArray(key).size() - 1 >= i)) {
                                        target.getJSONArray(key).add(valueArray.get(i));
                                    }
                                    JSONObject jsonObject = (JSONObject) target.getJSONArray(key).get(i);
                                    JSONObject targetValue = jsonMerge(obj, jsonObject);
                                    target.getJSONArray(key).set(i, targetValue);
                                }
                            }
                        }
                    }
                } else {
                    if (value != null) {
                        String sourceV = value.toString();
                        if (StringUtils.isNotBlank(sourceV)) {
                            if (splitStringKey.contains(key)) {
                                if (target.containsKey(key)) {
                                    if (null != target.get(key)) {
                                        Set set = new HashSet();
                                        set.addAll(Arrays.asList(sourceV.split(",")));
                                        target.put(key, set.stream().collect(Collectors.toList()));
                                    }
                                }
                            } else {
                                target.put(key, value);
                            }
                        }
                    }

                }
            }
        }
        return target;
    }

    private String buildBillType(Integer code) {
        switch (code) {
            case 1:
                return "DZ";
            case 2:
                return "DH";
            case 3:
                return "GC";
            case 4:
                return "DT";
            case 5:
                return "YD";
            case 6:
                return "SX";
            case 7:
                return "DL";
            case 8:
                return "MB";
            case 9:
                return "KK";
            case 10:
                return "KJ";
        }
        return "";
    }

    @Override
    public void seekNextNode(AppCreateJobBill appCreateJobBill) {
        MesSendOrderConfig mesSendOrderConfig = new MesSendOrderConfig();
        mesSendOrderConfig.setYn(YnStatusEnum.Y.getCode());
        mesSendOrderConfig.setJobType(Integer.valueOf(appCreateJobBill.getJobType()));

        if (appCreateJobBill.getJobType().equals(JobTypeInitEnum.GROUNDBREAKING_SECURITY_JOB_BILL.getCode().toString())) {
            JSONObject object = JSONObject.parse(appCreateJobBill.getContent());
            Object zyjb = object.get("zyjb");
            mesSendOrderConfig.setJobGrade(zyjb.toString());
        }

        if (appCreateJobBill.getJobType().equals(JobTypeInitEnum.HOT_WORK_SECURITY_JOB_BILL.getCode().toString())) {
            JSONObject object = JSONObject.parse(appCreateJobBill.getContent());
            Object dhzyjb = object.get("dhzyjb");
            mesSendOrderConfig.setJobGrade(dhzyjb.toString());
        }

        List<MesSendOrderConfig> mesSendOrderConfigs = mesSendOrderConfigMapper.queryAll(mesSendOrderConfig);
        if (CollectionUtils.isEmpty(mesSendOrderConfigs)) {
            return;
        }

        Map<Integer, List<MesSendOrderConfig>> listMap = mesSendOrderConfigs.stream()
                .collect(Collectors.groupingBy(MesSendOrderConfig::getJobSort));
        JSONObject jsonObject = JSON.parseObject(appCreateJobBill.getContent());
        if (null == jsonObject) {
            return;
        }

        AtomicBoolean flag = new AtomicBoolean(true);
        List<String> nodeList = new ArrayList<>();
        listMap.forEach((k, v) -> {
            if (flag.get()) {
                for (MesSendOrderConfig var : v) {
                    if (!jsonObject.containsKey(var.getNodeName())) {
                        nodeList.add(var.getNodeName());
                        flag.set(false);
                        break;
                    }
                }
            }
        });

        if (CollectionUtils.isEmpty(nodeList)) {
            return;
        }

        log.info("匹配到的节点:{}", JSON.toJSONString(nodeList));

        AppJobSignedConfig appJobSignedConfig = new AppJobSignedConfig();
        appJobSignedConfig.setYn(YnStatusEnum.Y.getCode());
        appJobSignedConfig.setJobType(appCreateJobBill.getJobType());

        if (appCreateJobBill.getJobType().equals(JobTypeInitEnum.GROUNDBREAKING_SECURITY_JOB_BILL.getCode().toString())) {
            JSONObject object = JSONObject.parse(appCreateJobBill.getContent());
            Object zyjb = object.get("zyjb");
            appJobSignedConfig.setJobGrade(zyjb.toString());
        }

        if (appCreateJobBill.getJobType().equals(JobTypeInitEnum.HOT_WORK_SECURITY_JOB_BILL.getCode().toString())) {
            JSONObject object = JSONObject.parse(appCreateJobBill.getContent());
            Object dhzyjb = object.get("dhzyjb");
            appJobSignedConfig.setJobGrade(dhzyjb.toString());
        }

        List<AppJobSignedConfig> appJobSignedConfigList = appJobSignedConfigMapper.queryAll(appJobSignedConfig);
        Map<String, List<AppJobSignedConfig>> configMap = appJobSignedConfigList.stream().collect(Collectors.groupingBy(AppJobSignedConfig::getNodeName));

        List<AppJobSignedConfig> appJobSignedConfigs = new ArrayList<>();
        for (String var : nodeList) {
            if (null != configMap.get(var)) {
                List<AppJobSignedConfig> jobSignedConfigs = configMap.get(var);
                appJobSignedConfigs.addAll(jobSignedConfigs);
            }
        }

        String desc = JobTypeInitEnum.valueOfCode(Integer.valueOf(appCreateJobBill.getJobType())).getDesc();

        JobPlanBillDeclare jobPlanBillDeclare = new JobPlanBillDeclare();
        jobPlanBillDeclare.setBillNumber(appCreateJobBill.getPtw());
        List<JobPlanBillDeclare> jobPlanBillDeclares = jobPlanBillDeclareService.queryAll(jobPlanBillDeclare);
        JobPlanBillDeclare planBillDeclare = jobPlanBillDeclares.stream().findFirst().orElse(new JobPlanBillDeclare());

        sendJobSignToNeedUpdNameSeek(appJobSignedConfigs, planBillDeclare.getBillNumber(), desc, appCreateJobBill.getSpecialNumber());
    }

    @Override
    @SuppressWarnings("all")
    public Integer countCreateJobBill(Integer operateType) {
        int sum = 0;
        AppCreateJobBill appCreateJobBill = new AppCreateJobBill();
        appCreateJobBill.setYn(YnStatusEnum.Y.getCode());
        List<AppCreateJobBill> appCreateJobBills = appCreateJobBillDao.queryAll(appCreateJobBill);
        if (CollectionUtils.isEmpty(appCreateJobBills)) {
            return 0;
        }

        for (AppCreateJobBill var : appCreateJobBills) {
            String content = var.getContent();
            if (!StringUtils.isEmpty(content)) {
                JSONObject jsonObject = JSON.parseObject(content);
                if (jsonObject.containsKey("jobDate")) {
                    List<String> jobDate = (List<String>) jsonObject.get("jobDate");
                    if (countCreateJobBill(jobDate, operateType)) {
                        sum++;
                    }
                }
            }
        }

        return sum;
    }

    @Override
    @SuppressWarnings("all")
    public List<JobTypeCountVO> countCreateJobBillTwo(Integer operateType) {
        List<JobTypeCountVO> response = new ArrayList<>();
        List<JobTypeCountVO> init = new ArrayList<>();

        AppCreateJobBill appCreateJobBill = new AppCreateJobBill();
        appCreateJobBill.setYn(YnStatusEnum.Y.getCode());
        List<AppCreateJobBill> appCreateJobBills = appCreateJobBillDao.queryAll(appCreateJobBill);
        if (CollectionUtils.isEmpty(appCreateJobBills)) {
            return response;
        }

        for (AppCreateJobBill var : appCreateJobBills) {
            String content = var.getContent();
            if (!StringUtils.isEmpty(content)) {
                JSONObject jsonObject = JSON.parseObject(content);
                if (jsonObject.containsKey("jobDate")) {
                    List<String> jobDate = (List<String>) jsonObject.get("jobDate");
                    if (countCreateJobBill(jobDate, operateType)) {
                        JobTypeCountVO jobTypeCountVO = new JobTypeCountVO();
                        jobTypeCountVO.setJobType(Integer.valueOf(var.getJobType()));
                        jobTypeCountVO.setCount(1);
                        init.add(jobTypeCountVO);
                    }
                }
            }
        }

        Map<Integer, List<JobTypeCountVO>> listMap = init.stream().collect(Collectors.groupingBy(JobTypeCountVO::getJobType));
        listMap.forEach((k, v) -> {
            JobTypeCountVO result = new JobTypeCountVO();
            result.setJobType(k);
            result.setCount(v.stream().map(JobTypeCountVO::getCount).reduce(Integer::sum).get());
            response.add(result);
        });

        return response;
    }

    private boolean countCreateJobBill(List<String> param, Integer operateType) {
        Date date = null;
        try {
            //获取当前日期
            Date currentDate = new Date();
            if (operateType.equals(YnStatusEnum.Y.getCode())) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
                String formattedDate = sdf.format(currentDate);
                date = sdf.parse(formattedDate);

                Date startDate = sdf.parse(param.get(0));
                Date endDate = sdf.parse(param.get(1));

                if (startDate.equals(date)) {
                    return true;
                }
            } else if (operateType.equals(YnStatusEnum.N.getCode())) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String formattedDate = sdf.format(currentDate);
                date = sdf.parse(formattedDate);

                Date startDate = sdf.parse(param.get(0));
                Date endDate = sdf.parse(param.get(1));

                //需要兼容开始时间跟结束时间一致的情况
                if ((date.after(startDate) && date.before(endDate))
                        || (date.equals(startDate) && date.equals(endDate))) {
                    return true;
                }
            } else {
                //获取本周的开始时间
                String startDate = getStartWeeksInMonthOfDate();
                //获取本周的结束时间
                String endDate = getEndWeeksInMonthOfDate();

                SimpleDateFormat sdfVar = new SimpleDateFormat("yyyy-MM-dd");
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                //票的开始时间
                Date startDateVar = sdfVar.parse(param.get(0));
                //票的结束时间
                Date endDateVar = sdfVar.parse(param.get(1));

                Date startDateOne = sdf.parse(startDate);
                Date endDateOne = sdf.parse(endDate);

                log.info(param.get(0) + "票的开始时间" + startDate + "获取本周的开始时间" +
                        param.get(1) + "票的结束时间" + endDate + "获取本周的结束时间");

                if (endDateVar.before(startDateOne) || startDateVar.after(endDateOne)) {
                    return false;
                } else {
                    return true;
                }


            }
        } catch (Exception e) {
            log.error("日期转换异常:{}", e.toString());
        }
        return false;
    }

    public static String getStartWeeksInMonthOfDate() {
        //设置格式
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        //创建Calendar 的实例
        Calendar calendar = Calendar.getInstance();
        //当前时间减去一天，即一天前的时间
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        return simpleDateFormat.format(calendar.getTime()) + " 00:00:00";
    }

    public static String getEndWeeksInMonthOfDate() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_WEEK, cal.getActualMaximum(Calendar.DAY_OF_WEEK));
        cal.add(Calendar.DAY_OF_WEEK, 1);
        Date time = cal.getTime();
        return new SimpleDateFormat("yyyy-MM-dd").format(time) + " 23:59:59";
    }

    private void sendJobSignToNeedUpdNameSeek(List<AppJobSignedConfig> appJobSignedConfigList, String pwt, String billName, String builCode) {
        log.info("推送审批节点信息详情:{}", JSON.toJSONString(appJobSignedConfigList));
        List<SysActing> sysActings = new ArrayList<>();
        appJobSignedConfigList.forEach(var -> {
            String planName = "作业计划" + pwt + billName + builCode + "正在" + var.getNodeNameValue() + "签批，请尽快完成！";
            SysActing sysActing = new SysActing();
            sysActing.setTitleName("签批特殊作业票");
            sysActing.setTitleType("");
            sysActing.setTitleInfo(planName);
            sysActing.setOriginatorId(1);
            sysActing.setOriginatorName("admin");
            sysActing.setExecutorId(var.getSignedBy());
            sysActing.setExecutorName(var.getSignedName());
            sysActing.setState(YnStatusEnum.N.getCode());
            sysActings.add(sysActing);
        });

        if (CollectionUtils.isEmpty(sysActings)) {
            return;
        }

        sysActingService.insertBatch(sysActings);

        List<Integer> list = appJobSignedConfigList.stream().map(AppJobSignedConfig::getSignedBy).collect(Collectors.toList());
        List<SysUser> vidsInfo = sysUserMapper.getVidsInfo(list);
        if (CollectionUtils.isEmpty(vidsInfo)) {
            return;
        }

        EnterpriseWXServiceImpl.SendMessageRequest sendMessageRequest = new EnterpriseWXServiceImpl.SendMessageRequest();
        sendMessageRequest.setTouser(vidsInfo.stream().map(SysUser::getWxUserId).collect(Collectors.joining("|")));
        sendMessageRequest.setMsgtype("text");
        sendMessageRequest.setAgentid(1000319);
        EnterpriseWXServiceImpl.MessageContent messageContent = new EnterpriseWXServiceImpl.MessageContent();
        AppJobSignedConfig appJobSignedConfig = appJobSignedConfigList.stream().findFirst().orElse(new AppJobSignedConfig());
        String planName = "作业计划" + pwt + billName + builCode + "正在" + appJobSignedConfig.getNodeNameValue() + " 签批，请尽快完成！";
        messageContent.setContent(planName);
        sendMessageRequest.setText(messageContent);
        enterpriseWXService.pushMessage(sendMessageRequest);
    }


}
